package com.insight.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.insight.common.constant.CommonConstant;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.SysPermission;
import com.insight.modules.system.entity.SysPermissionDataRule;
import com.insight.modules.system.mapper.SysPermissionDataRuleMapper;
import com.insight.modules.system.mapper.SysPermissionMapper;
import com.insight.modules.system.service.ISysPermissionDataRuleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 菜单权限规则  服务实现类
 * </p>
 *
 * @Author huangzhilin
 * @since 2019-04-01
 */
@Service
public class SysPermissionDataRuleImpl extends ServiceImpl<SysPermissionDataRuleMapper, SysPermissionDataRule>
		implements ISysPermissionDataRuleService {

	@Resource
	private SysPermissionMapper sysPermissionMapper;

	/**
	 * 根据菜单ID查询其对应的权限数据规则列表
	 * @param permissionId 菜单权限ID
	 * @return 对应的权限数据规则列表，按创建时间降序排序
	 */
	@Override
	public List<SysPermissionDataRule> getPermRuleListByPermId(String permissionId) {
		LambdaQueryWrapper<SysPermissionDataRule> query = new LambdaQueryWrapper<>();
		query.eq(SysPermissionDataRule::getPermissionId, permissionId);
		query.orderByDesc(SysPermissionDataRule::getCreateTime);
		List<SysPermissionDataRule> permRuleList = this.list(query);
		return permRuleList;
	}

	/**
	 * 根据前端传递的权限规则名称和权限规则值模糊查询权限数据规则
	 * @param permRule 传入的包含规则名称和规则值的实体对象
	 * @return 查询到的权限数据规则列表
	 */
	@Override
	public List<SysPermissionDataRule> queryPermissionRule(SysPermissionDataRule permRule) {
		QueryWrapper<SysPermissionDataRule> queryWrapper = new QueryWrapper<>();
		// 判断并模糊匹配规则名称
		if (permRule.getRuleName() != null && !permRule.getRuleName().isEmpty()) {
			queryWrapper.lambda().like(SysPermissionDataRule::getRuleName, permRule.getRuleName());
		}
		// 判断并模糊匹配规则值
		if (permRule.getRuleValue() != null && !permRule.getRuleValue().isEmpty()) {
			queryWrapper.lambda().like(SysPermissionDataRule::getRuleValue, permRule.getRuleValue());
		}
		return this.list(queryWrapper);
	}

	/**
	 * 根据用户名和权限ID查询对应的权限数据规则列表
	 * @param username 用户名
	 * @param permissionId 权限ID
	 * @return 用户对应的权限数据规则列表，若无匹配返回null
	 */
	@Override
	public List<SysPermissionDataRule> queryPermissionDataRules(String username, String permissionId) {
		List<String> idsList = this.baseMapper.queryDataRuleIds(username, permissionId);
		// 如果无对应权限规则ID，返回null
		if(idsList == null || idsList.isEmpty()) {
			return null;
		}
		// 利用Set去重权限规则ID
		Set<String> set = new HashSet<>();
		for (String ids : idsList) {
			if(oConvertUtils.isEmpty(ids)) {
				continue;
			}
			String[] arr = ids.split(",");
			for (String id : arr) {
				if(oConvertUtils.isNotEmpty(id)) {
					set.add(id);
				}
			}
		}
		if(set.isEmpty()) {
			return null;
		}
		// 查询状态为启用的权限数据规则列表
		return this.baseMapper.selectList(new QueryWrapper<SysPermissionDataRule>()
				.in("id", set)
				.eq("status", CommonConstant.STATUS_1));
	}

	/**
	 * 保存权限数据规则，并更新对应权限的规则标志位为已启用
	 * @param sysPermissionDataRule 权限数据规则实体
	 */
	@Override
	@Transactional
	public void savePermissionDataRule(SysPermissionDataRule sysPermissionDataRule) {
		this.save(sysPermissionDataRule);
		// 查询对应权限
		SysPermission permission = sysPermissionMapper.selectById(sysPermissionDataRule.getPermissionId());
		// 若权限存在且规则标志为空或为禁用状态，则更新为启用
		if(permission != null && (permission.getRuleFlag() == null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0))) {
			permission.setRuleFlag(CommonConstant.RULE_FLAG_1);
			sysPermissionMapper.updateById(permission);
		}
	}

	/**
	 * 删除权限数据规则，并根据是否存在其他规则，更新权限的规则标志
	 * @param dataRuleId 权限数据规则ID
	 */
	@Override
	@Transactional
	public void deletePermissionDataRule(String dataRuleId) {
		SysPermissionDataRule dataRule = this.baseMapper.selectById(dataRuleId);
		if(dataRule != null) {
			// 删除权限数据规则
			this.removeById(dataRuleId);
			// 查询该权限下剩余的规则数
			Integer count = this.baseMapper.selectCount(new LambdaQueryWrapper<SysPermissionDataRule>()
					.eq(SysPermissionDataRule::getPermissionId, dataRule.getPermissionId()));
			// 事务中删除后查询时数据已被删除，若事务回滚则删除无效
			if(count == null || count == 0) {
				// 查询对应权限
				SysPermission permission = sysPermissionMapper.selectById(dataRule.getPermissionId());
				// 若权限存在且规则标志为启用，则改为禁用
				if(permission != null && permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_1)) {
					permission.setRuleFlag(CommonConstant.RULE_FLAG_0);
					sysPermissionMapper.updateById(permission);
				}
			}
		}
	}
}

